﻿

package actionscripts{


	import flash.display.MovieClip;
	import flash.media.Camera;
	import flash.media.Video;
	import fl.data.DataProvider;
	import flash.events.MouseEvent;
	import fl.controls.ComboBox;
	import flash.utils.Timer;
	import flash.text.TextField;
	import flash.events.TimerEvent;
	import flash.display.BitmapData;
	import flash.geom.Matrix;
	import flash.net.FileReference;
	import flash.display.Bitmap;
	import fl.controls.Button;
	import flash.events.StatusEvent;
	import fl.controls.TileList;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.utils.ByteArray;
	import flash.events.ActivityEvent
	import flash.sampler.Sample;
	
    import flash.system.Security;
	import flash.system.SecurityPanel;
	import flash.system.System;
	import flash.events.*;
	import flash.geom.Rectangle;
	import flash.display.DisplayObject;




	import nochump.util.zip.*;
	import flash.net.FileFilter;
	
	import flash.net.URLRequest;
	import flash.net.URLLoader;
	import flash.net.URLRequestMethod;
	import flash.net.URLLoaderDataFormat;
	import flash.system.LoaderContext;
	import flash.net.URLVariables;
	import flash.external.ExternalInterface;
	import fl.motion.easing.Back;
	import fl.controls.Label;
	import flash.display.Loader;
	import flash.net.URLRequestHeader;
	
	public class main extends MovieClip {
		
		private var transferMatrix:Matrix = null;

		private var camWidth:int = 320;
		private var camHeight:int = 240;

		//set to 61 seconds in order to take 20 photos
		private var minTimer:Timer = new Timer(61000);// 1min  61000
		private var secTimer:Timer = new Timer(1000);//  1s
		private var photoTimer:Timer = new Timer(3000);// 3s
		
		private var cameraCheckTimer:Timer = new Timer(5000);

		private var second:int;

		private var video:Video;
		private var cam:Camera = null;

		private var snapshots:Array = new Array();

		private var zipTool :ZipOutput = null;
		
		private var counter:int  = 0;
		
		private var servletURL:String = null;
		
		public function main() {
			// constructor code
			trace("main be invoked");

			minTimer.addEventListener(TimerEvent.TIMER, minTimerHandler);
			secTimer.addEventListener(TimerEvent.TIMER, secTimerHandler);
			photoTimer.addEventListener(TimerEvent.TIMER,photoTimerHandler);
			cameraCheckTimer.addEventListener(TimerEvent.TIMER,cameraBusyCheckTimerHandler);
			
			flash.system.Security.allowDomain("*");
			
			checkCameraExist();//check whether camera exist
			
			initilization();
			
			ExternalInterface.addCallback("callFlashCameraStart",jsStart);
		
		}
		
		private function checkCameraExist():void{
			
			var tempCam:Camera = Camera.getCamera();
			
			if(null == tempCam){
				
				ExternalInterface.call("window.cvvObj.updateClientinfoCamera","no");
			}
			else{
				
				ExternalInterface.call("window.cvvObj.updateClientinfoCamera","yes");
			}
		}
		
		private function allowFunction():void{ //flash call js function
			
			if(this.cameraCheckTimer != null ){
				
				this.cameraCheckTimer.start();
			}
			
		}
		
		private function jsStart():void{
			
			//connect to the camera, if success, then begin timer
			try{
				refreshVariables();
				
				if(this.cam!=null && !this.cam.muted&&!this.isCameraOccupy(this.cam)) {
				
					second = 0;
				
					startAllTimer();
				
					trace("User clicked Accept.");
				
				}else {
					
					this.connectCamera();
				
					stopAllTimer();
		
					trace("User clicked Deny.");
				}
			}catch(e:SecurityError){
					//alertInfo.text = e.toString();
			}
		}
		
		private function loadPictureModel():void{
			

			var testClip:MovieClip = new MovieClip();
			var urlRequest:URLRequest = new URLRequest("http://d-shc-00361023:8081/testFlash2/pictureModel.png");
			var loader:Loader = new Loader();
			
			loader.load(urlRequest);
			
			this.addChild(loader);
													   
		}
		
		private function initilization():void {
			
			camWidth = videoBg.width;
			camHeight = videoBg.height;
			
			loadTargetURL();
			
			connectCamera();
		}
		
		private function loadTargetURL():void {
			
			this.servletURL = this.getCurrentPageUrl();
		}
		
		private function getCurrentPageUrl():String {
			
		    var url:String = null;
			
			try{
				if(ExternalInterface.available){
					
					 url = ExternalInterface.call('eval','window.location.href');
			
				}
			}catch(e:SecurityError) {
				
				//nothing
			}
			finally {
				
				if(url != null){
				
				var resultURL:String = url.split("&")[0];
				resultURL = resultURL+"&action=uploadPhoto";
				
				return resultURL;
				
				}
				else {
					
					return null;
				}
			}
		}
		
		
		
		private function SendPictureToServer(binaryData:ByteArray):void {

			 //  this.servletURL = "http://sjc-vts-348.dev.ebay.com:8080/ws/eBayISAPI.dll?VideoVerification&action=uploadPhoto"; 
			 // this.servletURL = "http://d-shc-00361023:8081/testFlash2/flashVertificationServlet";

			  if(this.servletURL !=null){
				  	
					ExternalInterface.call("alert",this.servletURL);
					
					var scriptRequest:URLRequest = new URLRequest(this.servletURL);
					var scriptLoader:URLLoader = new URLLoader();
		
					this.configureListeners(scriptLoader);
					
					scriptRequest.method = URLRequestMethod.POST;
					scriptRequest.contentType="text/html;charset=utf-8";
					
					scriptLoader.dataFormat = URLLoaderDataFormat.BINARY;
					
					var resultData:ByteArray = addTypecode(binaryData);
					scriptRequest.data = resultData;
					
					scriptLoader.load(scriptRequest);
					
					ExternalInterface.call("alert",resultData.length);
					
				 }else {
					 
					 ExternalInterface.call("alert","can not get target Url!");
				 }
				
		}
		
		private function addTypecode(binaryData:ByteArray):ByteArray {
			
			var resultData:ByteArray  = new ByteArray();
			resultData.writeUTFBytes("ZDATA");
			resultData.writeBytes(binaryData,0,binaryData.length);
			
			return resultData;
			
		}
		
		 private function configureListeners(dispatcher:IEventDispatcher):void {
			 
            dispatcher.addEventListener(Event.COMPLETE, completeHandler);
            dispatcher.addEventListener(Event.OPEN, openHandler);
            dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
            dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
            dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        }
		
		
		private function completeHandler(event:Event):void {
			
            var loader:URLLoader = URLLoader(event.target);
			
			var resultContent:String  = loader.data;
			var success:Boolean  = false;
			
			var SUCCESS:String = "UPLOAD_PHOTO_SUCCESS";
			
			if(resultContent.search(SUCCESS) > -1 ){
				
				ExternalInterface.call("window.cvvObj.finishInstruction","");
				
			}
			
        }

        private function openHandler(event:Event):void {

            trace("openHandler: " + event);
        }

        private function progressHandler(event:ProgressEvent):void {
			
            trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
        }

        private function securityErrorHandler(event:SecurityErrorEvent):void {
		
            trace("securityErrorHandler: " + event);
        }

        private function httpStatusHandler(event:HTTPStatusEvent):void {
			
            trace("httpStatusHandler: " + event);
        }

        private function ioErrorHandler(event:IOErrorEvent):void {
			
            trace("ioErrorHandler: " + event);
        }
		
		
		private function handleLoadSuccessful(evt:Event):void {
			
	　　　  trace("Message sent.");
	　　　  trace("DataReceived:" + evt.target.data);
			
		    this.zipTool = null;
		}
		
		private function handleLoadError(evt:IOErrorEvent):void {
			
		　　　 trace("Message failed._2");
		}
		
		private function socketCloseHandler(event:Event):void {
			
			trace("server close current socket!");
		}
		
		private function addZipEntry(fileName:String, byteArray:ByteArray):void {
			
			if(this.zipTool == null) {
				
				this.zipTool = new ZipOutput();
			}
			
			var zipEntry:ZipEntry = new ZipEntry(fileName);
	
			this.zipTool.putNextEntry(zipEntry);
			this.zipTool.write(byteArray);
			this.zipTool.closeEntry();
			
		}
		
		function stopAllTimer():void {
			
			secTimer.stop();
			photoTimer.stop();
			minTimer.stop();
		}
		
		function startAllTimer():void {
			minTimer.start();
			secTimer.start();
			photoTimer.start();
		}
		
		
		function cameraBusyCheckTimerHandler(e:TimerEvent):void{
			
			if(!this.cam.muted){
				
				if(this.isCameraOccupy(this.cam)){
						
					this.clearResource();
				
					disconnectCamera();
				
					ExternalInterface.call("alert","Camera is occupied or denied!");
				
				}else{//available
					
					ExternalInterface.call("window.cvvObj.enableStartForReady","");
				}
			
			this.cameraCheckTimer.stop();
			
			}
		}
		
		function minTimerHandler(e:TimerEvent) {

			stopAllTimer();
			
			this.zipTool.finish();
			
			SendPictureToServer(this.zipTool.byteArray);
			
		}

		function secTimerHandler(e:TimerEvent) {
			
			second++;
		}

		function photoTimerHandler(e:TimerEvent) {
			
			takeSnapshot();
		}
		
		private function cameraHorizontal(displayObject:DisplayObject):Matrix {
			
			
			var matrix:Matrix = displayObject.transform.matrix;	
			matrix.a=-1;	
			matrix.tx=displayObject.width+displayObject.x;	
			
			return matrix;
			
			
		}
		
		protected function isCameraOccupy(camera:Camera) :Boolean {
			
			if(camera == null) {
				
				return true;
			}else if(camera.currentFPS == 0){
				
				return true;
			}else{
				
				return false;
			}
		}
		
		protected function connectCamera():Boolean {
			
				if(cam == null){ // just create one cam instance
				
					cam = Camera.getCamera();//use Camera selected in  Security box
					
					if(cam != null){
						cam.addEventListener(StatusEvent.STATUS,statusHandler);
					}
					
				}
				
				if(video == null) {
					
					video = new Video(camWidth,camHeight);
					
					if(video != null){
						video.addEventListener(Event.ADDED,addVideoHandler);
					}
						
				}
				
				
				if(this.cam != null) {
					
					cam.setQuality(100,0);//quality precedence , highest quality without the limit of bandwidth
										  //size of data is relevant with picture size ,that is , camera's size
					cam.setMode(camWidth,camHeight,80);
					
					if(this.cam.muted) {
						
						Security.showSettings(SecurityPanel.PRIVACY);
					}
					else{
						
						allowFunction();
					}
				
					this.addChild(video);
					
					video.attachCamera(cam);
					video.x = videoBg.x;
					video.y = videoBg.y;
					
					transferMatrix = cameraHorizontal(video);
					
					video.transform.matrix = transferMatrix;
					
					loadPictureModel();
					
					trace("current use: "+ cam.name);
					
				}
				
			return true;
		}
		
		protected function addVideoHandler(event:Event):void {
			
			
		}

		protected function statusHandler(event:StatusEvent):void {
			
			switch (event.code) {
				case "Camera.Muted" :{
					
					 disconnectCamera();
				
					 secTimer.stop();
					 photoTimer.stop();
					 minTimer.stop();
				
				 	trace("User clicked Deny.");
					 break;
				 
			    } 
				
				case "Camera.Unmuted" :{
				
					 connectCamera();
					 if(!this.cam.muted){
						 	
							
					 }
					 second = 0;
					 trace("User clicked Accept.");
					 break;
				}
		 	}
		}

		protected function disconnectCamera() {
			
			this.removeChild(video);
			//after this statement, the webcam will be shutdown 
			video.attachCamera(null);
			
			this.clearResource();
			
			
		}

		protected function clearResource():void {
			this.zipTool = null;
			this.counter = 0;
			
		}
		
		protected function refreshVariables() :void {
			this.zipTool = null;
			this.counter = 0;
			
			
		}
		
		protected function takeSnapshot() {
			
			var snapshot:BitmapData = new BitmapData(camWidth,camHeight);
			snapshot.draw(video,transferMatrix);
			
			var bmp:Bitmap = new Bitmap(snapshot);
			bmp.width = 120;
			bmp.height = 90;
			
			var jpgEncoder:JPGEncoder = new JPGEncoder(80);
			var jpgDataArray:ByteArray = jpgEncoder.encode(bmp.bitmapData);
			
			
			
			this.addZipEntry(new String(counter + ".jpg"),jpgDataArray);
			counter++;

		}


	}

}